package com.bringspring.system.permission.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bringspring.common.base.GlobalMarkEnum;
import com.bringspring.common.base.UserInfo;
import com.bringspring.common.util.JsonUtil;
import com.bringspring.common.util.RandomUtil;
import com.bringspring.common.util.StringUtils;
import com.bringspring.common.util.UserProvider;
import com.bringspring.system.base.exception.BaseException;
import com.bringspring.system.permission.constant.PermissionConst;
import com.bringspring.system.permission.entity.*;
import com.bringspring.system.permission.mapper.RoleMapper;
import com.bringspring.system.permission.model.authorize.AuthorizeConditionModel;
import com.bringspring.system.permission.model.organize.OrganizePagination;
import com.bringspring.system.permission.model.role.RolePagination;
import com.bringspring.system.permission.model.role.RoleUpForm;
import com.bringspring.system.permission.service.*;
import com.github.pagehelper.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 系统角色
 *
 * @author 开发平台组
 * @version V1.0.0
 * @copyright 股份有限公司
 * @date 2017年9月26日 上午9:18
 */
@Service
@DSTransactional
public class RoleServiceImpl extends ServiceImpl<RoleMapper, RoleEntity> implements RoleService {

    @Autowired
    private UserProvider userProvider;
    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private UserRelationService userRelationService;
    @Autowired
    private AuthorizeService authorizeService;
    @Autowired
    private OrganizeRelationService organizeRelationService;
    @Autowired
    private OrganizeService organizeService;

    @Override
    public List<RoleEntity> getList() {
        QueryWrapper<RoleEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().orderByAsc(RoleEntity::getSortCode).orderByDesc(RoleEntity::getCreatorTime);
        return this.list(queryWrapper);
    }

    @Override
    public List<RoleEntity> getList(RolePagination pagination) {

        QueryWrapper<RoleEntity> queryWrapper = new QueryWrapper<>();
        // null:全部显示 0：全局
        if (!userProvider.get().getIsAdministrator()) {
            Object obj = queryWrapper;
            queryWrapper = (QueryWrapper<RoleEntity>) authorizeService.getCondition(new AuthorizeConditionModel(queryWrapper, pagination.getMenuId(),"BASE_ROLE"));
        }
        int globalMark;
        if("0".equals(pagination.getOrganizeId())){
            // 显示全局
            globalMark = 1;
        }else if(StringUtils.isEmpty(pagination.getOrganizeId())){
            // 全部显示
            globalMark = -1;
        }else {
            // 显示组织内
            globalMark = 0;
        }
        // 定义变量判断是否需要使用修改时间倒序
        boolean flag = false;
        if (StringUtils.isNotEmpty(pagination.getKeyword())) {
            flag = true;
            queryWrapper.lambda().and(t -> t.like(RoleEntity::getFullName, pagination.getKeyword()).or().like(RoleEntity::getEnCode, pagination.getKeyword()));
        }
        // 组织id查询相关的角色
        if (globalMark == 0) {
            List<OrganizeEntity> listLikeOrgIdTree = organizeService.getListLikeOrgIdTree(pagination.getOrganizeId());

            QueryWrapper<OrganizeRelationEntity> queryRelation = new QueryWrapper<>();
            queryRelation.lambda().eq(OrganizeRelationEntity::getOrganizeId, pagination.getOrganizeId());
            List<String> ids = new ArrayList<>();
            organizeRelationService.list(queryRelation).forEach(o -> {
                ids.add(o.getObjectId());
            });
            if (ids.size() > 0) {
                queryWrapper.lambda().in(RoleEntity::getId, ids);
            } else {
                queryWrapper.lambda().in(RoleEntity::getId, "0");
            }
        }

        if (globalMark != -1) {
            queryWrapper.lambda().eq(RoleEntity::getGlobalMark, globalMark);
        }
        queryWrapper.lambda().orderByAsc(RoleEntity::getSortCode).orderByDesc(RoleEntity::getCreatorTime);
        if (flag) {
            queryWrapper.lambda().orderByDesc(RoleEntity::getLastModifyTime);
        }
        Page<RoleEntity> page = new Page<>(pagination.getCurrentPage(), pagination.getPageSize());
        IPage<RoleEntity> userPage = this.page(page, queryWrapper);
        return pagination.setData(userPage.getRecords(), page.getTotal());
    }
    @Override
    public List<RoleEntity> getListByDataPermission(RolePagination pagination) {
        UserInfo userInfo = userProvider.get();
        QueryWrapper<RoleEntity> queryWrapper = new QueryWrapper<>();


        QueryWrapper<OrganizeRelationEntity> queryRelation = new QueryWrapper<>();
        //条件过滤
        if (StringUtils.isNotEmpty(pagination.getOrganizeId())) {
            List<String> childOrganizeIds = organizeService.getUnderOrganizations(pagination.getOrganizeId());
            childOrganizeIds.add(pagination.getOrganizeId());
            queryRelation.lambda().in(CollectionUtil.isNotEmpty(childOrganizeIds),OrganizeRelationEntity::getOrganizeId, childOrganizeIds);
        }
        //全局
        if (StringUtils.isNotEmpty(pagination.getOrganizeId())&&"0".equals(pagination.getOrganizeId())){
            queryWrapper.lambda().eq(RoleEntity::getGlobalMark, GlobalMarkEnum.NOT_ORGANIZE.getCode());
        }
            //非管理员只能查看组织角色；只有管理员管理员，显示全局角色
        if (!userInfo.getIsAdministrator()) {
            queryWrapper.lambda().eq(RoleEntity::getGlobalMark, GlobalMarkEnum.ORGANIZE.getCode());
            //查询数据权限组织角色
            List<OrganizeEntity> organizeByDataAuthorize = organizeService.getOrganizeByDataPermission(new OrganizePagination(pagination.getMenuId()));
            List<String> organizeIds = organizeByDataAuthorize.stream().map(OrganizeEntity::getId).collect(Collectors.toList());
            //过滤数据权限所属组织
            queryRelation.lambda().in(CollectionUtil.isNotEmpty(organizeIds),OrganizeRelationEntity::getOrganizeId, organizeIds);
        }

        List<String> ids = new ArrayList<>();
        organizeRelationService.list(queryRelation).forEach(o -> {
            ids.add(o.getObjectId());
        });
        //如果数据权限和条件过滤完以后部门和角色管理为空，则返回空数据  ; 判断是否为全局 如果是全局 前端返回值是--0
        if (!"0".equals(pagination.getOrganizeId())){
            if (CollectionUtil.isEmpty(ids)) {
                queryWrapper.lambda().in(RoleEntity::getId, "");
            }else{
//            不为空，当前组织下有角色，查询有值
                queryWrapper.lambda().in(RoleEntity::getId, ids);
            }
        }

        if (StringUtils.isNotEmpty(pagination.getKeyword())) {
            queryWrapper.lambda().and(t -> t.like(RoleEntity::getFullName, pagination.getKeyword()).or().like(RoleEntity::getEnCode, pagination.getKeyword()));
        }
        //过滤角色分类
        if (CollectionUtil.isNotEmpty(pagination.getTypeList())){
            queryWrapper.lambda().in(RoleEntity::getType,pagination.getTypeList());
        }

        queryWrapper.lambda().orderByAsc(RoleEntity::getSortCode).orderByDesc(RoleEntity::getLastModifyTime);
        Page<RoleEntity> page = new Page<>(pagination.getCurrentPage(), pagination.getPageSize());
        IPage<RoleEntity> userPage = this.page(page, queryWrapper);
        return pagination.setData(userPage.getRecords(), page.getTotal());
    }
    @Override
    public List<RoleEntity> getListByEnCode(String enCode) {
        QueryWrapper<RoleEntity> query = new QueryWrapper<>();
        query.lambda().in(RoleEntity::getEnCode, enCode);
        return this.list(query);

    }

    @Override
    public List<RoleEntity> getListByUserId(String userId) {
        QueryWrapper<RoleEntity> query = new QueryWrapper<>();
        List<String> roleRelations = userRelationService.getListByObjectType(userId, PermissionConst.ROLE).stream().map(UserRelationEntity::getObjectId).collect(Collectors.toList());
        if (roleRelations.size() > 0) {
            query.lambda().in(RoleEntity::getId, roleRelations);
            return this.list(query);
        } else {
            return new ArrayList<>();
        }
    }

    @Override
    public List<RoleEntity> getListByUserIdAndOrgId(String userId, String orgId) {
        return getListByUserId(userId).stream().filter(role -> organizeRelationService.existByObejctIdAndOrgIdAndObjectType(orgId,role.getId(), PermissionConst.ROLE)).collect(Collectors.toList());
    }

    @Override
    public List<String> getRoleIdsByCurrentUser() {
        UserEntity userEntity = userService.getInfo(userProvider.get().getUserId());
        return getAllRoleIdsByUserIdAndOrgId(userEntity.getId(), userEntity.getOrganizeId());
    }

    @Override
    public List<String> getRoleIdsByCurrentUser(String orgId) {
        UserEntity userEntity = userService.getInfo(userProvider.get().getUserId());
        return getAllRoleIdsByUserIdAndOrgId(userEntity.getId(), orgId);
    }

    @Override
    public List<String> getAllRoleIdsByUserIdAndOrgId(String userId, String orgId) {
        // 用户当前组织下的角色
        List<String> roleIds = getListByUserIdAndOrgId(userId, orgId).stream().map(RoleEntity::getId).collect(Collectors.toList());
        // 用户绑定的全局角色
        List<String> globalRoleIds = userRelationService.getListByUserIdAndObjType(userId, PermissionConst.ROLE).stream().map(UserRelationEntity::getObjectId).collect(Collectors.toList());
        globalRoleIds = roleService.getListByIds(globalRoleIds).stream().filter(r -> r.getGlobalMark() != null && r.getGlobalMark() == GlobalMarkEnum.NOT_ORGANIZE.getCode()).map(RoleEntity::getId).collect(Collectors.toList());
        roleIds.addAll(globalRoleIds);
        return roleIds.stream().distinct().collect(Collectors.toList());
    }

    @Override
    public RoleEntity getInfo(String id) {
        QueryWrapper<RoleEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(RoleEntity::getId, id);
        return this.getOne(queryWrapper);
    }

    @Override
    public Boolean isExistByFullName(String fullName, String id) {
        QueryWrapper<RoleEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(RoleEntity::getFullName, fullName);
        if (!StringUtils.isEmpty(id)) {
            queryWrapper.lambda().ne(RoleEntity::getId, id);
        }
        return this.count(queryWrapper) > 0 ? true : false;
    }

    @Override
    public Boolean isExistByEnCode(String enCode, String id) {
        QueryWrapper<RoleEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(RoleEntity::getEnCode, enCode);
        if (!StringUtils.isEmpty(id)) {
            queryWrapper.lambda().ne(RoleEntity::getId, id);
        }
        return this.count(queryWrapper) > 0 ? true : false;
    }

    @Override
    public Boolean update(String id, RoleEntity entity) {
        entity.setId(id);
        return this.updateById(entity);
    }

    @Override
    public void create(RoleEntity entity) {

        this.save(entity);
    }

    @Override
    @DSTransactional
    public void copyRole(RoleUpForm roleUpForm, String fromId) throws BaseException {

        RoleEntity entity = JsonUtil.getJsonToBean(roleUpForm, RoleEntity.class);
        if (roleService.isExistByFullName(roleUpForm.getFullName(), null)) {
            throw new BaseException("角色名称不能重复");
        }
        if (roleService.isExistByEnCode(roleUpForm.getEnCode(), null)) {
            throw new BaseException("角色编码不能重复");
        }
        entity.setId(RandomUtil.uuId());
        //创建角色
        this.save(entity);

        this.createOrganizeRoleRelation(roleUpForm.getOrganizeIdsTree(), entity.getId(), entity.getGlobalMark());
        //复制数据
        List<AuthorizeEntity> authorizeEntities = authorizeService.getListByObjectId(fromId);
        for (AuthorizeEntity authorizeEntity : authorizeEntities) {
            authorizeEntity.setObjectId(entity.getId());
            authorizeEntity.setId(RandomUtil.uuId());
            authorizeService.save(authorizeEntity);
        }

    }
    /**
     * 添加组织角色关联关系
     */
    @Override
    @DSTransactional
    public Boolean createOrganizeRoleRelation(List<List<String>> organizeIdsTree, String roleId, Integer globalMark) {
        // 清除之前的关联关系
        QueryWrapper<OrganizeRelationEntity> query = new QueryWrapper<>();
        query.lambda().eq(OrganizeRelationEntity::getObjectType, PermissionConst.ROLE);
        query.lambda().eq(OrganizeRelationEntity::getObjectId, roleId);
        organizeRelationService.remove(query);
        // globalMark等于0时，为组织角色
        if(globalMark.equals(0)) {
            List<OrganizeRelationEntity> relationList = new ArrayList<>();
            for (List<String> organizeIds : organizeIdsTree) {
                // 组织id数组树最后一个数组最后一个id，是需要储存的id
                String organizeId = organizeIds.get(organizeIds.size() - 1);
                // 添加与组织的关联关系
                OrganizeRelationEntity organizeRelationEntity = new OrganizeRelationEntity();
                organizeRelationEntity.setId(RandomUtil.uuId());
                organizeRelationEntity.setOrganizeId(organizeId);
                organizeRelationEntity.setObjectType(PermissionConst.ROLE);
                organizeRelationEntity.setObjectId(roleId);
                relationList.add(organizeRelationEntity);
            }
            organizeRelationService.saveBatch(relationList);
        }
        return true;
    }
    @Override
    @DSTransactional
    public void delete(RoleEntity entity) {
        if (entity != null) {
            this.removeById(entity.getId());
            QueryWrapper<AuthorizeEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(AuthorizeEntity::getObjectId, entity.getId());
            authorizeService.remove(queryWrapper);
            QueryWrapper<UserRelationEntity> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(UserRelationEntity::getObjectId, entity.getId());
            userRelationService.remove(wrapper);
        }
    }
    /**
     * 根据菜单id获取角色列表信息
     * @param menuId
     * @return
     */
    @Override
    public List<AuthorizeEntity> getListBymenuId(String menuId) {
        QueryWrapper<AuthorizeEntity> query = new QueryWrapper<>();
        query.lambda().eq(AuthorizeEntity::getItemType, "module");
        query.lambda().eq(AuthorizeEntity::getItemId, menuId);
        query.lambda().eq(AuthorizeEntity::getObjectType, "Role");
        List<AuthorizeEntity> ls = authorizeService.list(query);
        List<AuthorizeEntity> distinctPersons = ls.stream()
                .collect(Collectors.toMap(AuthorizeEntity::getObjectId, p -> p, (p1, p2) -> p1))
                .values()
                .stream()
                .collect(Collectors.toList());
        return distinctPersons;
    }

    @Override
    public List<RoleEntity> getListByIds(List<String> id) {
        List<RoleEntity> roleList = new ArrayList<>();
        if (id.size() > 0) {
            QueryWrapper<RoleEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().in(RoleEntity::getId, id);
            roleList = this.list(queryWrapper);
        }
        return roleList;
    }

    @Override
    public RoleEntity getInfoByFullName(String fullName) {
        QueryWrapper<RoleEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(RoleEntity::getFullName, fullName);
        return this.getOne(queryWrapper);
    }

    @Override
    public List<RoleEntity> getGlobalList() {
        QueryWrapper<RoleEntity> query = new QueryWrapper<>();
        query.lambda().eq(RoleEntity::getGlobalMark, GlobalMarkEnum.NOT_ORGANIZE.getCode());
        return this.list(query);
    }


    @Override
    public List<RoleEntity> getCurRolesByOrgId(String orgId) {
        String userId = userProvider.get().getUserId();
        List<UserRelationEntity> userRelations = userRelationService.getListByObjectType(userId, PermissionConst.ROLE);
        List<RoleEntity> roles = new ArrayList<>();
        userRelations.forEach(ur -> {
            // 获取全局角色
            RoleEntity roleEntity = this.getInfo(ur.getObjectId());
            if (roleEntity != null && roleEntity.getGlobalMark() != null && roleEntity.getGlobalMark() == GlobalMarkEnum.NOT_ORGANIZE.getCode()) {
                roles.add(roleEntity);
            } else {
                organizeRelationService.getRelationListByRoleId(ur.getObjectId()).forEach(or -> {
                    if (or.getOrganizeId().equals(orgId)) {
                        roles.add(roleEntity);
                    }
                });
            }
        });
        return roles;
    }

    @Override
    public List<RoleEntity> getRolesByOrgId(String orgId) {
        List<String> ids = new ArrayList<>();
        organizeRelationService.getListByTypeAndOrgId(PermissionConst.ROLE, orgId).forEach(o -> {
            ids.add(o.getObjectId());
        });
        QueryWrapper<RoleEntity> query = new QueryWrapper<>();
        if (ids.size() > 0) {
            query.lambda().in(RoleEntity::getId, ids);
            return this.list(query);
        } else {
            return new ArrayList<>();
        }
    }

    @Override
    public String getBindInfo(String roleId, List<String> reduceOrgIds) {
        if (reduceOrgIds.size() > 0) {
            StringBuilder info = new StringBuilder();
            RoleEntity roleEntity = this.getInfo(roleId);
            List<UserRelationEntity> bingUserByRoleList = userRelationService.getListByObjectId(roleId, PermissionConst.ROLE);
            if (bingUserByRoleList.size() < 1) {
                return null;
            }
            info.append("已绑定用户：");
            boolean bindFlag = false;
            for (UserRelationEntity bingUser : bingUserByRoleList) {
                String userId = bingUser.getUserId();
                //角色是全局，
                if (roleEntity.getGlobalMark() == GlobalMarkEnum.NOT_ORGANIZE.getCode()) {
                    UserEntity user = userService.getInfo(userId);
                    info.append("[ ").append(user.getRealName()).append(" ] ");
                    bindFlag = true;
                } else {
                    // 这个用户所绑定的组织
                    List<UserRelationEntity> bingUserByOrg = userRelationService.getListByObjectType(userId, PermissionConst.ORGANIZE);
                    for (UserRelationEntity bingOrg : bingUserByOrg) {
                        String orgId = bingOrg.getObjectId();
                        for (String reduceOrgId:reduceOrgIds){
//                            判断角色所属组织和角色下的用户所属组织是否有相同的
                          if (reduceOrgId.equals(orgId)) {
                            OrganizeEntity org = organizeService.getInfo(orgId);
                            UserEntity user = userService.getInfo(bingOrg.getUserId());
                            info.append("[").append(org.getFullName()).append("：用户（").append(user.getRealName()).append("）]; ");
                            bindFlag = false;
                            break;
                          }else{
                            bindFlag = true;
                          }
                        }
                    }
                }
            }
            if (bindFlag) {
                return info.toString();
            } else {
                return null;
            }
        } else {
            return null;
        }
    }
}
